# coding: utf-8

import os
import re
import time

import config
import handler.http as httpHandler
import handler.jsonp as jsonHandler
import handler.image as imageHandler
from handler.cookie import CookieHandler
from handler.file import FileHandler
from handler.http import get_requests_cookie
from model.attribute_dict import AttributeDict
from model.utils import current_random
from handler.selenium_handler import By, NoSuchElementException, SeleniumHandler

from . import logger


class ZhonghuaSpider(object):

    def __init__(self, file_handler=None):
        self.cookie_name = 'zhonghua'
        self.base_url = 'http://query.cic.cn'
        self.query_url = self.base_url + '/autoclaim/epiq/main.jsp'
        self.start_url = self.base_url + '/autoclaim/control/policysearch?actionType=query'
        self.verify_code_url = self.base_url + '/autoclaim/control/loadCheckCode?id={0}'
        self.cookie_handler = CookieHandler()
        if file_handler is None:
            file_handler = FileHandler()
        self.file_handler = file_handler

    def __get_cookie_to_dict(self):
        return self.cookie_handler.get_cookie_to_dict(self.cookie_name)

    def __get(self, url):
        self.selenium = SeleniumHandler()
        self.selenium.maximize_window()
        self.selenium.get(url)
        time.sleep(1)
        self.cookies = self.selenium.get_cookies()

    def __get_current_url(self):
        return self.selenium.get_current_url()

    def __download_to_image(self, url):
        ''' 通过链接下载图形验证码 '''
        header_new = config.HEADER
        header_new['Cookie'] = self.cookie_handler.list_to_string(self.cookies)
        cookies = httpHandler.get_requests_cookie(self.cookies)
        return imageHandler.download_to_image(url, headers=header_new, cookies=cookies)

    def __verify_code_crack(self):
        image_url = self.verify_code_url.format(current_random())
        image = self.__download_to_image(image_url)
        code = imageHandler.image_to_string(image, lang='chi_sim')
        if code:
            code = code.replace(os.linesep, '')
            code = code.replace('\t', '')
        return code

    def __query_page(self, policy_no, idcard_no):
        verify_code = ''
        while not verify_code:
            verify_code = self.__verify_code_crack()
        logger.info('verify code: {0}'.format(verify_code))
        self.selenium.get_element('/html/body/form/div/table/tbody/tr[1]/td[2]/input').send_keys(policy_no)
        self.selenium.get_element('/html/body/form/div/table/tbody/tr[2]/td[2]/input').send_keys(idcard_no)
        self.selenium.get_element('/html/body/form/div/table/tbody/tr[3]/td[2]/input').send_keys(verify_code)
        self.selenium.get_element('/html/body/form/div/table/tbody/tr[4]/td[2]/input').click()
        is_exists_notice = self.selenium.execute_script('return document.getElementById("otherFiled_notice");')
        if is_exists_notice is not None:
            notice_message = self.selenium.get_element_text('//*[@id="otherFiled_notice"]')
            logger.info(notice_message)
            if notice_message.find(u'您所查询的保单本日已达到查询次数上限') > -1:
                return False
            elif notice_message.find(u'您输入的查询条件无匹配数据') > -1:
                self.file_handler.write_queried(self.policy_no, 0)
                logger.info('policy no [{0}] not found info!'.format(self.policy_no))
                return False
            elif notice_message.find(u'验证码不正确') > -1:
                time.sleep(1)
                self.__query_page(policy_no, idcard_no)
        else:
            logger.info('policy no [{0}] queried info!'.format(self.policy_no))
            self.query_handler = self.selenium.get_current_window()
            show_element = self.selenium.get_element('/html/body/form/div[1]/div[1]/table/tbody/tr[2]/td[5]/a')
            show_element.click()
            self.__result_page()

    def __result_page(self):
        try:
            self.selenium.switch_to_window_by_index(1)
            self.selenium.wait((By.CLASS_NAME, 'td_unit'))
            policy_info = AttributeDict()
            policy_info.policy_no = self.selenium.get_element_text('/html/body/form/div[4]/div[1]/table[1]/tbody/tr[2]/td[2]') # 保单号
            policy_info.policy_the_name = self.selenium.get_element_text('/html/body/form/div[4]/div[1]/table[1]/tbody/tr[2]/td[4]')  # 被保险人
            policy_info.policy_date_time = self.selenium.get_element_text('/html/body/form/div[4]/div[1]/table[1]/tbody/tr[2]/td[6]') # 保险期限
            policy_info.policy_name = self.selenium.get_element_text('/html/body/form/div[4]/div[1]/table[1]/tbody/tr[3]/td[2]') # 产品名称
            policy_info.policy_status = self.selenium.get_element_text('/html/body/form/div[4]/div[1]/table[1]/tbody/tr[3]/td[4]') # 保单状态
            policy_info.policy_total_money = self.selenium.get_element_text('/html/body/form/div[4]/div[1]/table[1]/tbody/tr[3]/td[6]') # 保单总保费
            policy_info.withhold_fare_money = self.selenium.get_element_text('/html/body/form/div[4]/div[1]/table[1]/tbody/tr[4]/td[2]')  # 代收车船税金额
            policy_info.policy_total_coefficient = self.selenium.get_element_text('/html/body/form/div[4]/div[1]/table[1]/tbody/tr[4]/td[4]')  # 保单使用总系数
            policy_info.policy_holder_name = self.selenium.get_element_text('/html/body/form/div[4]/div[1]/table[1]/tbody/tr[4]/td[6]')  # 投保人
            insurance_type_list = []
            table2_trs = self.selenium.get_elements('/html/body/form/div[4]/div[1]/table[2]/tbody/tr')
            for (index,tr) in enumerate(table2_trs):
                if index < 2:
                    continue
                table2_tds = tr.find_elements_by_tag_name('td')
                insurance_type = AttributeDict()
                insurance_type.guarantee_project = table2_tds[0].text  # 险别名称
                insurance_type.sum_insured = table2_tds[1].text  # 保险金额/责任限额
                insurance_type.annual_premium = ''  # 标准保费
                insurance_type.rate_floating_coefficient = table2_tds[2].text # 费率浮动系数
                insurance_type.payment_premium = table2_tds[3].text  # 保费金额
                insurance_type.rate_floating_cause = ''  # 费率浮动事由
                insurance_type_list.append(insurance_type)
            policy_info.insurance_type_list = insurance_type_list
            table3_tds = self.selenium.get_elements('/html/body/form/div[4]/div[1]/table[3]/tbody/tr[3]/td')
            policy_info.channel_type = table3_tds[0].text  # 渠道类型
            policy_info.agency_name = table3_tds[2].text  # 代理机构/人名称
            policy_info.agency_code = table3_tds[3].text  # 机构代码/职业资格证书代码
            policy_info.payment_method = table3_tds[4].text  # 支付方式
            policy_info.payment_object = table3_tds[1].text  # 支付对象
            pay_list = []
            table_last_trs = self.selenium.get_elements('/html/body/form/div[4]/div[3]/table/tbody/tr')
            for (index,tr) in enumerate(table_last_trs):
                if index == 0:
                    continue
                table_last_tds = tr.find_elements_by_tag_name('td')
                pay_info = AttributeDict()
                pay_info.type = table_last_tds[1].text # 费用类型
                pay_info.policy_no = table_last_tds[2].text # 保单/批单号码
                pay_info.money = table_last_tds[3].text # 金额
                pay_info.pay_money = table_last_tds[4].text # 已付金额
                pay_info.no_pay_money = table_last_tds[5].text # 未付金额
                pay_list.append(pay_info)
            policy_info.pay_list = pay_list
            # logger.info(jsonHandler.to_json(policy_info))
            self.file_handler.write_result_json(policy_info)
            logger.info('policy no [{0}] save info!'.format(self.policy_no))
        finally:
            self.selenium.close().switch_to_window(self.query_handler).refresh()

    def __handler(self, policy_no, idcard_no):
        self.policy_no = policy_no
        self.idcard_no = idcard_no
        try:
            logger.info('current query policy no: [{0}], idcard no: [{1}]'.format(policy_no, idcard_no))
            self.__query_page(self.policy_no, self.idcard_no)
        except Exception as e:
            logger.log(e)
            logger.error(e)
        logger.info('current query complete!', split=True)

    def run(self, policy_no, idcard_no):
        if self.file_handler.check_queried(policy_no):
            self.__get(self.start_url)
            self.__handler(policy_no, idcard_no)
            self.exit()

    def batch_run(self, query_list):
        logger.info('total of {0} data!'.format(len(query_list)), split=True)
        self.__get(self.start_url)
        for (idcard_no, policy_no) in query_list:
            if self.file_handler.check_queried(policy_no):
                self.__handler(policy_no, idcard_no)
                time.sleep(1)
        self.exit()
        logger.info('all query complete!', split=True)

    def exit(self):
        self.selenium.exit()
